<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of "myWiWall".
# Copyright (c) 2007-2008 CRP Henri Tudor and contributors.
# All rights reserved.
#
# "myWiWall" is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as published by
# the Free Software Foundation.
# 
# "myWiWall" is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with "myWiWall"; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# ***** END LICENSE BLOCK *****

/**
 * widget resource class
 */
class res_widget implements RESTResource 
{
	
 	/**
 	 * extension asked
 	 */	
	private $ext;
	
 	/**
 	 * reference to the request object
 	 */	
	private	$request;
	
	
	/**
	 * authenticated user
	 */
	private $userid;
	
	/**
	 * authenticated user level
	 */	
	private $userlevel;

	private $tag;
	
	private $category;

	// FIXME extension pour Palette
	private $app;

 	/**
 	 * Constructor
 	 * @param	HttpRequest		$pReq			request
 	 * @param	string			$pExt			extension
 	 * @param	array			$pConstraints	list of constraints on this resource
 	 */
    public function __construct(RESTHttpRequest $pReq, $pExt = null, $pConstraints = array()) 
    {
    	// FIXME extension pour Palette
		foreach($pConstraints as $constraint) {
			if ($constraint[0] == 'app') {
				$this->app = $constraint[1];
			}
			if ($constraint[0] == 'tag') {
				$this->tag = $constraint[1];
			}
			if ($constraint[0] == 'category') {
				$this->category = $constraint[1];
			}			
		}

    	$this->request = $pReq;
    	$this->ext = $pExt;    	
    }
    
 	/**
 	 * Tests if a string is an id for this resource class (this method is optional)
 	 * @param	string	$pInputStr	the string tested
 	 * @return	integer	0 for false, and 1 for true (not boolean because this method is called by call_user_func)
 	 */
    public static function isId($pInputStr) 
    {
    	return 1;
    }

 	/**
 	 * authentication
 	 * @param	string		$pLogin	login
 	 * @param	string		$pPass	password
 	 * @return	boolean				true if the login is successful or if it is a public resource 
 	 */    
    public function auth($pLogin, $pPass) 
    {
		$db = DbUtil::accessFactory();
		$pLogin = $db->escape($pLogin);
		$pPass = md5($db->escape($pPass));
		
		$rs = $db->select("SELECT id, level FROM users WHERE username = '${pLogin}' AND password = '${pPass}'");
	
		/* Check if a result was found */
		if ($rs->count())
		{
			$this->userid 		= $rs->id;
			$this->userlevel 	= $rs->level;
			
			return true;
		}
		
		return false;
    }

	// *** read-only rest methods *** //

 	/**
 	 * list of items (this method is optional)
	 * WARNING: this method should not modify data (REST "Safety" concept)
 	 * GET /item 
 	 * or HEAD /item
 	 * @param	boolean	$pHead	true if we return only headers
 	 */
    public function index($pHead = false) 
    {
		$db = DbUtil::accessFactory();
    
		header('Content-type: text/xml');
		
		if ($pHead) {
			return;
		}
		
		echo '<?xml version="1.0"?>';
		
		$query = null;
		
		if (isset($_GET['q']) && !empty($_GET['q'])) 
		
			$rs = $db->select("(SELECT widgetid FROM widgets WHERE visible= 1 AND (description LIKE '%${_GET['q']}%' OR widgetname LIKE '%${_GET['q']}%')) UNION (SELECT widgetid FROM widgets INNER JOIN widget_tags ON widgets.widgetid = widget_tags.widget WHERE visible= 1 AND widget_tags.tag LIKE '${_GET['q']}') UNION (SELECT widgetid FROM widgets INNER JOIN categories ON widgets.category = categories.id WHERE visible= 1 AND categories.category LIKE '%${_GET['q']}') ORDER BY widgetid ASC");		
		
		else if ($this->app) 
		
			// FIXME extension pour Palette
			$rs = $db->select("SELECT widgetid FROM widgets,widget_app WHERE visible= 1 AND widgets.widgetid = widget_app.widget_id AND service_id = '$this->app' ORDER BY widgetid ASC");
		
		else if ($this->tag) 
		
			$rs = $db->select("SELECT widgetid FROM widgets, widget_tags WHERE visible= 1 AND widgets.widgetid = widget_tags.widget AND widget_tags.tag = '$this->tag' ORDER BY widgetid ASC");			
		
		else if ($this->category) 
		
			$rs = $db->select("SELECT widgetid FROM widgets, categories WHERE visible= 1 AND widgets.category = categories.id AND categories.category = '$this->category' ORDER BY widgetid ASC");						
		
		else 
		
			$rs = $db->select("SELECT widgetid FROM widgets WHERE visible= 1 ORDER BY widgetname ASC");							
		
			
		// XML flow output.
		echo '<widgets>';
		
		while ($rs->fetch())
		{
			echo '<widget>'.BASE_WS_URL.'widget/'.$rs->widgetid.'</widget>';
		}		
		
		echo '</widgets>';
    }

 	/**
 	 * display an item (this method is optional)
	 * WARNING: this method should not modify data (REST "Safety" concept)
 	 * GET /item/id
 	 * or HEAD /item/id
 	 * @param	string		@pId	id of the resource
 	 * @param	boolean 	$pHead	true if we return only headers
 	 */    
    public function show($pId, $pHead = false) 
    {
		$db = DbUtil::accessFactory();
    
		$rs = $db->select("SELECT widgetid, widgetname,category FROM widgets WHERE visible = 1 AND widgetid = '${pId}'");

		if ($rs->count())
		{		
			header('Content-type: text/xml');    	
			
			// If head request, simply return headers.
			if ($pHead) 
				return;
				
			echo '<?xml version="1.0"?>';		

			$id = $rs->widgetid;
			$cat = $rs->category;
			// r�cup�ration des tags
			$rs2 = $db->select("SELECT tag FROM widget_tags WHERE widget = '${id}'");
			
			$tags = '';
			
			while ($rs2->fetch())
				$tags .= '<tag>'.BASE_WS_URL.'tag/'.$rs2->tag.'</tag>';

				
			// r�cup�ration de la cat�gorie.
			$cats = '<category />';
			if ($cat !== null) 
			{
				$rs3 	= $db->select("SELECT categories.category FROM categories WHERE id = ${cat}");
				$cats 	= '$db';
				
				while ($rs->fetch())
					$cats = '<category>'.BASE_WS_URL.'category/'.$rs3->category.'</category>';
			}

			
			// r�cup�ration de la description et de l'auteur
			$doc = new DOMDocument();
			$doc->preserveWhiteSpace = false;
			
			// Does the manifest exists ? (defensive)
			if (!$doc->load(dirname(__FILE__) . '/../../widgets/' . $id . '/config.xml')) 
				throw new RESTException('Unable to load manifest config.xml', 500);
			
			$descs = $doc->getElementsByTagName('description');
			$descs = $descs->item(0);
			$desc = null;
			
			if ($descs) 
			{
				$descs = $descs->childNodes->item(0);

				if ($descs->nodeType == XML_TEXT_NODE) 
				{
					$desc = $descs->nodeValue;
				}
			}
			$authors = $doc->getElementsByTagName('author');
			$author = $authors->item(0);

			$sshot = BASE_PREVIEW_DIR .$pId.'.jpg';
			$sshotURI = BASE_PREVIEW_URI .$pId.'.jpg';
			
			if (!file_exists($sshot)) {
				$sshotURI = '';
			}

			echo '<widget>';
			echo '<name>'.$rs->widgetname.'</name>';
			
			if ($desc) {
				echo '<description>'.$desc.'</description>';
			}
			
			if ($author) {
				echo $doc->saveXML($author);
			}
			
			echo $cats;

			echo '<tags>'.$tags.'</tags>';
			echo '<preview>'.$sshotURI.'</preview>';
			echo '</widget>';
		} 
		else 
		{
			throw new RESTException("", 404);
		}		
		

    }

	// *** read-write rest methods *** //


 	/**
 	 * create an item (this method is optional)
 	 * POST /item
 	 */    
    public function create() {
    	
    }


 	/**
 	 * update an item (this method is optional)
	 * WARNING: this method should be idempotent (two calls to this method give the same result as one)
 	 * PUT /item/id
 	 * @param	string		@pId	id of the resource
 	 */        
    public function update($pId) {
    	
    }
    
 	/**
 	 * delete an item (this method is optional)
	 * WARNING: this method should be idempotent (two calls to this method give the same result as one)
 	 * DELETE /item/id
 	 * @param	string		@pId	id of the resource
 	 */
    public function delete($pId) {
    	
    }
}
?>
